|
|
@@ -6,18 +6,26 @@ module Agents
|
6
|
6
|
cannot_receive_events!
|
7
|
7
|
|
8
|
8
|
description <<-MD
|
9
|
|
- The WeatherAgent creates an event for the following day's weather at a given `location`.
|
|
9
|
+ The WeatherAgent creates an event for the day's weather at a given `location`.
|
10
|
10
|
|
11
|
|
- The `location` can be a US zipcode, or any location that Wunderground supports. To find one, search [wunderground.com](http://wunderground.com) and copy the location part of the URL. For example, a result for San Francisco gives `http://www.wunderground.com/US/CA/San_Francisco.html` and London, England gives `http://www.wunderground.com/q/zmw:00000.1.03772`. The locations in each are `US/CA/San_Francisco` and `zmw:00000.1.03772`, respectively.
|
|
11
|
+ You also must select `which_day` you would like to get the weather for where the number 0 is for today and 1 is for tomorrow and so on. Weather is only returned for 1 week at a time.
|
12
|
12
|
|
13
|
|
- You must setup an [API key for Wunderground](http://www.wunderground.com/weather/api/) in order to use this Agent.
|
|
13
|
+ The weather can be provided by either Wunderground or ForecastIO. To choose which `service` to use, enter either `forecastio` or `wunderground`.
|
|
14
|
+
|
|
15
|
+ The `location` can be a US zipcode, or any location that Wunderground supports. To find one, search [wunderground.com](http://wunderground.com) and copy the location part of the URL. For example, a result for San Francisco gives `http://www.wunderground.com/US/CA/San_Francisco.html` and London, England gives `http://www.wunderground.com/q/zmw:00000.1.03772`. The locations in each are `US/CA/San_Francisco` and `zmw:00000.1.03772`, respectively.
|
|
16
|
+
|
|
17
|
+ If you plan on using ForecastIO, the `location` must be a set of GPS coordinates.
|
|
18
|
+
|
|
19
|
+ You must setup an [API key for Wunderground](http://www.wunderground.com/weather/api/) in order to use this Agent with Wunderground.
|
|
20
|
+
|
|
21
|
+ You must setup an [API key for Forecast](https://developer.forecast.io/) in order to use this Agent with ForecastIO.
|
14
|
22
|
MD
|
15
|
23
|
|
16
|
24
|
event_description <<-MD
|
17
|
25
|
Events look like this:
|
18
|
26
|
|
19
|
27
|
{
|
20
|
|
- "location": 12345,
|
|
28
|
+ "location": "12345",
|
21
|
29
|
"date": {
|
22
|
30
|
"epoch": "1357959600",
|
23
|
31
|
"pretty": "10:00 PM EST on January 11, 2013"
|
|
|
@@ -44,38 +52,127 @@ module Agents
|
44
|
52
|
event_created_within?(2) && !recent_error_logs?
|
45
|
53
|
end
|
46
|
54
|
|
47
|
|
- def wunderground
|
48
|
|
- Wunderground.new(options['api_key']) if key_setup?
|
49
|
|
- end
|
50
|
|
-
|
51
|
55
|
def key_setup?
|
52
|
|
- options['api_key'] && options['api_key'] != "your-key"
|
|
56
|
+ options['api_key'].present? && options['api_key'] != "your-key"
|
53
|
57
|
end
|
54
|
58
|
|
55
|
59
|
def default_options
|
56
|
60
|
{
|
57
|
|
- 'api_key' => "your-key",
|
58
|
|
- 'location' => "94103"
|
|
61
|
+ 'service' => 'wunderground',
|
|
62
|
+ 'api_key' => 'your-key',
|
|
63
|
+ 'location' => '94103',
|
|
64
|
+ 'which_day' => '1'
|
59
|
65
|
}
|
60
|
66
|
end
|
61
|
67
|
|
|
68
|
+ def service
|
|
69
|
+ options["service"].presence || "wunderground"
|
|
70
|
+ end
|
|
71
|
+
|
|
72
|
+ def which_day
|
|
73
|
+ (options["which_day"].presence || 1).to_i
|
|
74
|
+ end
|
|
75
|
+
|
|
76
|
+ def location
|
|
77
|
+ options["location"].presence || options["zipcode"]
|
|
78
|
+ end
|
|
79
|
+
|
62
|
80
|
def validate_options
|
63
|
|
- errors.add(:base, "location is required") unless options['location'].present? || options['zipcode'].present?
|
64
|
|
- errors.add(:base, "api_key is required") unless options['api_key'].present?
|
|
81
|
+ errors.add(:base, "service is required") unless service.present?
|
|
82
|
+ errors.add(:base, "service must be set to 'forecastio' or 'wunderground'") unless ["forecastio", "wunderground"].include?(service)
|
|
83
|
+ errors.add(:base, "location is required") unless location.present?
|
|
84
|
+ errors.add(:base, "api_key is required") unless key_setup?
|
|
85
|
+ errors.add(:base, "which_day selection is required") unless which_day.present?
|
65
|
86
|
end
|
66
|
87
|
|
67
|
|
- def check
|
|
88
|
+ def wunderground
|
|
89
|
+ Wunderground.new(options['api_key']).forecast_for(location)['forecast']['simpleforecast']['forecastday'] if key_setup?
|
|
90
|
+ end
|
|
91
|
+
|
|
92
|
+ def forecastio
|
68
|
93
|
if key_setup?
|
69
|
|
- wunderground.forecast_for(options['location'] || options['zipcode'])["forecast"]["simpleforecast"]["forecastday"].each do |day|
|
70
|
|
- if is_tomorrow?(day)
|
71
|
|
- create_event :payload => day.merge('location' => options['location'] || options['zipcode'])
|
72
|
|
- end
|
|
94
|
+ ForecastIO.api_key = options['api_key']
|
|
95
|
+ lat, lng = location.split(',')
|
|
96
|
+ ForecastIO.forecast(lat,lng)['daily']['data']
|
|
97
|
+ end
|
|
98
|
+ end
|
|
99
|
+
|
|
100
|
+ def model(service,which_day)
|
|
101
|
+ if service == "wunderground"
|
|
102
|
+ wunderground[which_day]
|
|
103
|
+ elsif service == "forecastio"
|
|
104
|
+ forecastio.each do |value|
|
|
105
|
+ timestamp = Time.at(value.time)
|
|
106
|
+ if (timestamp.to_date - Time.now.to_date).to_i == which_day
|
|
107
|
+ day = {
|
|
108
|
+ 'date' => {
|
|
109
|
+ 'epoch' => value.time.to_s,
|
|
110
|
+ 'pretty' => timestamp.strftime("%l:%M %p %Z on %B %d, %Y"),
|
|
111
|
+ 'day' => timestamp.day,
|
|
112
|
+ 'month' => timestamp.month,
|
|
113
|
+ 'year' => timestamp.year,
|
|
114
|
+ 'yday' => timestamp.yday,
|
|
115
|
+ 'hour' => timestamp.hour,
|
|
116
|
+ 'min' => timestamp.strftime("%M"),
|
|
117
|
+ 'sec' => timestamp.sec,
|
|
118
|
+ 'isdst' => timestamp.isdst ? 1 : 0 ,
|
|
119
|
+ 'monthname' => timestamp.strftime("%B"),
|
|
120
|
+ 'monthname_short' => timestamp.strftime("%b"),
|
|
121
|
+ 'weekday_short' => timestamp.strftime("%a"),
|
|
122
|
+ 'weekday' => timestamp.strftime("%A"),
|
|
123
|
+ 'ampm' => timestamp.strftime("%p"),
|
|
124
|
+ 'tz_short' => timestamp.zone
|
|
125
|
+ },
|
|
126
|
+ 'period' => which_day.to_i,
|
|
127
|
+ 'high' => {
|
|
128
|
+ 'fahrenheit' => value.temperatureMax.round().to_s,
|
|
129
|
+ 'epoch' => value.temperatureMaxTime.to_s,
|
|
130
|
+ 'fahrenheit_apparent' => value.apparentTemperatureMax.round().to_s,
|
|
131
|
+ 'epoch_apparent' => value.apparentTemperatureMaxTime.to_s,
|
|
132
|
+ 'celsius' => ((5*(Float(value.temperatureMax) - 32))/9).round().to_s
|
|
133
|
+ },
|
|
134
|
+ 'low' => {
|
|
135
|
+ 'fahrenheit' => value.temperatureMin.round().to_s,
|
|
136
|
+ 'epoch' => value.temperatureMinTime.to_s,
|
|
137
|
+ 'fahrenheit_apparent' => value.apparentTemperatureMin.round().to_s,
|
|
138
|
+ 'epoch_apparent' => value.apparentTemperatureMinTime.to_s,
|
|
139
|
+ 'celsius' => ((5*(Float(value.temperatureMin) - 32))/9).round().to_s
|
|
140
|
+ },
|
|
141
|
+ 'conditions' => value.summary,
|
|
142
|
+ 'icon' => value.icon,
|
|
143
|
+ 'avehumidity' => (value.humidity * 100).to_i,
|
|
144
|
+ 'sunriseTime' => value.sunriseTime.to_s,
|
|
145
|
+ 'sunsetTime' => value.sunsetTime.to_s,
|
|
146
|
+ 'moonPhase' => value.moonPhase.to_s,
|
|
147
|
+ 'precip' => {
|
|
148
|
+ 'intensity' => value.precipIntensity.to_s,
|
|
149
|
+ 'intensity_max' => value.precipIntensityMax.to_s,
|
|
150
|
+ 'intensity_max_epoch' => value.precipIntensityMaxTime.to_s,
|
|
151
|
+ 'probability' => value.precipProbability.to_s,
|
|
152
|
+ 'type' => value.precipType
|
|
153
|
+ },
|
|
154
|
+ 'dewPoint' => value.dewPoint.to_s,
|
|
155
|
+ 'avewind' => {
|
|
156
|
+ 'mph' => value.windSpeed.round().to_s,
|
|
157
|
+ 'kph' => (Float(value.windSpeed) * 1.609344).round().to_s,
|
|
158
|
+ 'degrees' => value.windBearing.to_s
|
|
159
|
+ },
|
|
160
|
+ 'visibility' => value.visibility.to_s,
|
|
161
|
+ 'cloudCover' => value.cloudCover.to_s,
|
|
162
|
+ 'pressure' => value.pressure.to_s,
|
|
163
|
+ 'ozone' => value.ozone.to_s
|
|
164
|
+ }
|
|
165
|
+ return day
|
|
166
|
+ end
|
73
|
167
|
end
|
74
|
168
|
end
|
75
|
169
|
end
|
76
|
170
|
|
77
|
|
- def is_tomorrow?(day)
|
78
|
|
- Time.zone.at(day["date"]["epoch"].to_i).to_date == Time.zone.now.tomorrow.to_date
|
|
171
|
+ def check
|
|
172
|
+ if key_setup?
|
|
173
|
+ create_event :payload => model(service, which_day).merge('location' => location)
|
|
174
|
+ end
|
79
|
175
|
end
|
|
176
|
+
|
80
|
177
|
end
|
81
|
178
|
end
|